#include "stdafx.h"
#include "ActionPatcher.h"
#include <cassert>
#include <iostream>

void ActionPatcher::ModifyStreet(std::list<Action> &actions)
{
	list<Action>::iterator actionIt;
	map<string, ActionState>::iterator mapIt;
	Street streetPos = PREFLOP;
	bool switchState = false;

	for(actionIt = actions.begin(); actionIt != actions.end(); actionIt++)
	{
		if (switchState)
		{
			streetPos = (Street)((int)streetPos + 1);
			if ((int)streetPos > (int)RIVER) assert(0);
			switchState = false;
		}
		string playerName = (*actionIt).PlayerName();
		ActionType actionType = (*actionIt).ActionType();
		GetActionState(playerName, actionType);

		//for(mapIt = (this->actionMap_).begin(); mapIt != (this->actionMap_).end(); mapIt++)
		//{
		//	cout << "Name: " << (*mapIt).first << ", ActionState: " << (*mapIt).second  << endl;
		//}
		//cout << "$$$$$" << endl;

		switchState = GetStreet(streetPos, actions);
		(*actionIt).StreetPos(streetPos);
		
	}
	//cout << "~~~~~~~~~~~~~~~~~~~~~~~" << endl;
}

void ActionPatcher::UpdateMap()
{
	map<string, ActionState>::iterator mapIt;

	for(mapIt = (this->actionMap_).begin(); mapIt != (this->actionMap_).end(); mapIt++)
	{
		if ((*mapIt).second == CLEAN)
		{
			string playerName = (*mapIt).first;
			(this->actionMap_)[playerName] = DIRTY;
		}
	}
}

bool ActionPatcher::GetStreet(Street streetPos, list<Action> actions)
{
	int dirtyCount = 0;
	map<string, ActionState>::iterator mapIt;

	for(mapIt = (this->actionMap_).begin(); mapIt != (this->actionMap_).end(); mapIt++)
	{
		if((*mapIt).second == DIRTY) dirtyCount += 1;
	}

	if (dirtyCount == 0) 
	{
		for(mapIt = (this->actionMap_).begin(); mapIt != (this->actionMap_).end(); mapIt++)
		{
			if((*mapIt).second == CLEAN) (*mapIt).second = DIRTY;
		}
		return true;
	}

	return false;
}

void ActionPatcher::GetActionState(string playerName, ActionType actionType)
{
	bool bUpdateMap = false;
	switch(actionType)
		{
		case POST:
			(this->actionMap_)[playerName] = DIRTY;
			break;
		case CHECK:
			(this->actionMap_)[playerName] = CLEAN;
			break;
		case CALL:
			(this->actionMap_)[playerName] = CLEAN;
			break;
		case BET:
			UpdateMap();
			(this->actionMap_)[playerName] = CLEAN;
			break;
		case RAISE:
			UpdateMap();
			(this->actionMap_)[playerName] = CLEAN;
			break;
		case FOLD:
			(this->actionMap_)[playerName] = OUT;
			break;
		default:
			break;
		}
}

void ActionPatcher::Initialize(list<Action> &actions)
{
	list<Action>::iterator actionIt;
	map<string, ActionState>::iterator actionMapIt;

	if (actions.empty()) assert(0); // Error check: ensure action list is non empty

	for(actionIt = actions.begin(); actionIt != actions.end(); actionIt++)
	{
		string playerName = (*actionIt).PlayerName();
		(this->actionMap_)[playerName] = DIRTY;
	}
}

void ActionPatcher::UpdateActions(list<Action> &actions)
{
	Initialize(actions);
	ModifyStreet(actions);
}